package com.byedu.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.byedu.entity.*;
import com.byedu.service.PayBeanService;
import com.byedu.utils.*;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONObject;
import com.byedu.utils.http.HttpRequestUtil;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class PayController {


    @Resource
    private PayBeanService payBeanService;
    private static Logger logger = Logger.getLogger(PayController.class);


    @RequestMapping("/test")
    public void test(HttpServletRequest request,
                     final HttpServletResponse response
    ) throws IOException, ServletException {
        PhacseOrder po = new PhacseOrder();
        request.setAttribute("po", po);
        request.getRequestDispatcher("shop/test.jsp").forward(request, response);
    }

    @RequestMapping("/createOrder")
    public void createOrder(HttpServletRequest request,
                            final HttpServletResponse response,
                            @RequestParam(value = "userId") String userId,
                            @RequestParam(value = "courseId") String courseId
    ) throws IOException, ServletException {
        try {

            logger.error("userId:" + userId);
            logger.error("courseId:" + courseId);
            Course course = RectUrl.getCourseId(courseId, userId);
            ApiUserInfo userInfo = RectUrl.getUserbyId(userId, null);
            if (course.isPay()) {
                request.setAttribute("ErrorMsg", "该课程已经购买，不能重复购买");
                request.getRequestDispatcher("shop/havedbuy.jsp").forward(request, response);
                return;
            } else {

                if (!StringUtil.isNullOrEmpty(userInfo.getOpenId()) && !StringUtil.isNullOrEmpty(userId) && !StringUtil.isNullOrEmpty(courseId)) {

                    PhacseOrder pOrder = new PhacseOrder();
                    String orderId = "by" + Sha1Util.getTimeStamp();//随机生成了一个订单号
                    pOrder.setOrderId(orderId);
                    pOrder.setUserId(userId);
                    pOrder.setOpenId(userInfo.getOpenId());
                    pOrder.setCouseId(courseId);
                    pOrder.setAttendNum("5623");
                    //课程价格单位为分，需要转换为元
                    pOrder.setOrderManey("" + course.getPrice() / 100.0);
                    pOrder.setCouseName(course.getName());
                    pOrder.setCouseIntroduce(course.getIntro());
                    pOrder.setCouseImage(course.getImg());
                    pOrder.setConnectCompany("网络教学课程，购买后不能退款。最终解释权归贝易网校所有");
                    pOrder.setConnectPeople("微信：贝易网校 服务电话：1100023");

                    Calendar now = Calendar.getInstance();
                    String startTime = now.get(Calendar.YEAR) + "年" + (now.get(Calendar.MONTH) + 1) + "月" + now.get(Calendar.DAY_OF_MONTH) + "月";
                    pOrder.setStartTime(startTime);
                    String endTime = (now.get(Calendar.YEAR) + 1) + "年" + (now.get(Calendar.MONTH) + 1) + "月" + now.get(Calendar.DAY_OF_MONTH) + "月";
                    pOrder.setEndTime(endTime);

                    request.setAttribute("pOrder", pOrder);
                    request.getRequestDispatcher("shop/index.jsp").forward(request, response);
                } else {
                    request.setAttribute("ErrorMsg", "生成订单页面失败");
                    request.getRequestDispatcher("shop/error.jsp").forward(request, response);
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
            request.setAttribute("ErrorMsg", "生成订单页面失败");
            request.getRequestDispatcher("shop/error.jsp").forward(request, response);

        }
        //sb为微信返回的xml
    }


    @RequestMapping("/notifyServlet")
    public void notifyServlet(HttpServletRequest request,
                              final HttpServletResponse response) throws IOException, ServletException {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);

            }
            logger.error(sb.toString());
            Map ma = GetWxOrderno.doXMLParse(sb.toString());
            WechatNotifyBean my = (WechatNotifyBean) GetWxOrderno.mapToObject(ma, WechatNotifyBean.class);
            //签名验证
            PayBean endPayBean = new PayBean(my);
            PayBean checkPayBean = payBeanService.selectPayBeanId(endPayBean.getOut_trade_no());
//            logger.error("signweixin：："+endPayBean.getSign());
//            logger.error("signsave：："+checkPayBean.getSign());
//            if (endPayBean.getSign().equals(checkPayBean.getSign())){
            //签名验证成功，更新数据库信息，同时向api发送

            ApiUserInfo apiUserInfo = RectUrl.getUserbyId(null, endPayBean.getOpenid());

            if (apiUserInfo != null) {


                JSONObject jsonAdd = new JSONObject();
                jsonAdd.put("userId", apiUserInfo.getUserId());
                jsonAdd.put("courseId", checkPayBean.getCourse_id());

//                jsonAdd.put("purchaseTime",System.currentTimeMillis());
                jsonAdd.put("orderId", endPayBean.getOut_trade_no());

                String addString = HttpRequestUtil.sendPost(RectUrl.ADDUSERURL, jsonAdd);// 拿去返回值

                JSONObject jsonAddRelut = JSONObject.parseObject(addString);

                if (jsonAddRelut.getBoolean("success") && jsonAddRelut.getInteger("data") > 0) {
                    logger.error(addString);
                    endPayBean.setSuccess(true);
                    payBeanService.updatePayBean(endPayBean);

                    //向腾讯返回成功信息，避免重发
                    String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                    response.getWriter().append(result.toString());
                }
            }

        } catch (Exception ex) {
            ex.printStackTrace();

            request.setAttribute("ErrorMsg", "支付失败");
            request.getRequestDispatcher("shop/error.jsp").forward(request, response);


        }
        //sb为微信返回的xml
    }

    @RequestMapping("/topayServlet")
    public void topayServlet(HttpServletRequest request,
                             final HttpServletResponse response) throws IOException, ServletException {


        try {
            JSONObject json = new JSONObject();

            //远程获取价格，防止被篡改

            String openid = request.getParameter("openId");
            String courseId = request.getParameter("courseId");
            String trade_no = request.getParameter("orderId");
            String userId = request.getParameter("userId");
            Course course = RectUrl.getCourseId(courseId, userId);
            //金额 以分为单位，不带小数点
            int total_fee = course.getPrice();


            //用于获取随机数
            String currTime = TenpayUtil.getCurrTime();//获取当前时间
            String strTime = currTime.substring(8, currTime.length());//8位日期
            String strRandom = TenpayUtil.buildRandom(4) + "";//四位随机数
            String nonce_str = strTime + strRandom;//10位序列号,可以自行调整

            //商户号
            String mch_id = TenpayUtil.partner;
            //子商户号  非必输
//           String sub_mch_id = "10001";

            //订单生成的机器 IP
            String spbill_create_ip = request.getRemoteAddr();

            //非必输
//				String product_id = "";

            //获取sign（统一下单接口签名）
            //第一步，设所有发送或者接收到的数据为集合M，将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），
            //使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
            //第二步，在stringA最后拼接上key得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，
            //再将得到的字符串所有字符转换为大写，得到sign值signValue。
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", TenpayUtil.appid);
            packageParams.put("mch_id", mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", WeiXinPayUtil.body);
            packageParams.put("attach", courseId);
            packageParams.put("out_trade_no", trade_no);
            packageParams.put("total_fee", String.valueOf(total_fee));
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", RectUrl.NOTICEFYURL);
            packageParams.put("trade_type", WeiXinPayUtil.trade_type);
            packageParams.put("openid", openid);


            RequestHandler reqHandler = new RequestHandler(request, response);
            reqHandler.init(TenpayUtil.appid, TenpayUtil.appsecret, TenpayUtil.partnerkey);
            String sign = reqHandler.createSign(packageParams);

            //统一下单接口携带参数（xml格式），接口地址https://api.mch.weixin.qq.com/pay/unifiedorder
            String xml = "<xml>" +
             "<appid>" + TenpayUtil.appid + "</appid>" +
             "<mch_id>" + mch_id + "</mch_id>" +
//                   "<sub_mch_id>" + sub_mch_id + "</sub_mch_id>" +
             "<nonce_str>" + nonce_str + "</nonce_str>" +
             "<sign>" + sign + "</sign>" +
             "<body><![CDATA[" + WeiXinPayUtil.body + "]]></body>" +
             "<attach>" + courseId + "</attach>" +
             "<out_trade_no>" + trade_no + "</out_trade_no>" +
             //金额，这里写的1 分到时修改，测试用
//						"<total_fee>"+1+"</total_fee>"+
             "<total_fee>" + total_fee + "</total_fee>" +
             "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>" +
             "<notify_url>" + RectUrl.NOTICEFYURL + "</notify_url>" +
             "<trade_type>" + WeiXinPayUtil.trade_type + "</trade_type>" +
             "<openid>" + openid + "</openid>" +
             "</xml>";
            //System.out.println(xml);

            String allParameters = "";//没用

            allParameters = reqHandler.genPackage(packageParams);


            //请求微信统一下单接口，成功后返回预支付交易会话标识prepay_id
            String prepay_id = "";
            try {
                prepay_id = new GetWxOrderno().getPayNo(TenpayUtil.CREATEORDERURL, xml);
                if (prepay_id.equals("")) {
                    request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
                    request.getRequestDispatcher("shop/error.jsp").forward(request, response);
                    return;
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
                request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
                request.getRequestDispatcher("shop/error.jsp").forward(request, response);
            }

            //生成H5调起微信支付API相关参数（前端页面js的配置参数）
            SortedMap<String, String> finalpackage = new TreeMap<String, String>();
            String timestamp = Sha1Util.getTimeStamp();//当前时间的时间戳
            String packages = "prepay_id=" + prepay_id;
            ;//订单详情扩展字符串
            finalpackage.put("appId", TenpayUtil.appid);//公众号appid
            finalpackage.put("timeStamp", timestamp);
            finalpackage.put("nonceStr", nonce_str); //随机数
            finalpackage.put("package", packages);
            finalpackage.put("signType", "MD5");//签名方式
            String finalsign = reqHandler.createSign(finalpackage);//签名

            json.put("appId", TenpayUtil.appid);
            json.put("timeStamp", timestamp);
            json.put("nonceStr", nonce_str);
            json.put("packages", packages);
            json.put("sign", finalsign);
            logger.error("sign::" + sign);
            logger.error("finalsign::" + finalsign);
            //给api生成订单

            PayBean endPayBean = new PayBean();
            endPayBean.setAppid(TenpayUtil.appid);
            endPayBean.setCourse_id(courseId);
            endPayBean.setSuccess(false);
            endPayBean.setMch_id(TenpayUtil.partner);
//           endPayBean.setSub_mch_id(sub_mch_id);
            endPayBean.setOpenid(openid);
            endPayBean.setOut_trade_no(trade_no);
            endPayBean.setTotal_fee(String.valueOf(total_fee));
            endPayBean.setSign(finalsign);


            if (payBeanService.addPayBean(endPayBean) == 0) {
                request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");

                request.getRequestDispatcher("shop/error.jsp").forward(request, response);
                return;
            }

            response.getWriter().append(json.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
            request.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
            request.getRequestDispatcher("shop/error.jsp").forward(request, response);
            return;
        }
    }
}
